package jmine.tec.utils.poi;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

/**
 * Represents an Excel Workbook.
 * 
 * @author julien
 */
public class Workbook implements Iterable<Spreadsheet> {

    private HSSFWorkbook workbook;

    private Map<String, Spreadsheet> nameToSpreadsheet = new HashMap<String, Spreadsheet>();

    private Map<Integer, Spreadsheet> indexToSpreadsheet = new HashMap<Integer, Spreadsheet>();

    /**
     * C'tor
     * 
     * @param input An InputStream that is expected to be an Excel document
     * @throws IOException If the input stream is incorrect in some way
     */
    public Workbook(final InputStream input) throws IOException {
        POIFSFileSystem fs = new POIFSFileSystem(input);
        this.workbook = new HSSFWorkbook(fs);
        this.initialize();
    }

    /**
     * C'tor
     * 
     * @param file A File that is expected to be an Excel document
     * @throws IOException If any IO error occurs
     */
    public Workbook(final File file) throws IOException {
        this(new FileInputStream(file));
    }

    /**
     * C'tor
     * 
     * @param path The path to a file that is expected to be an Excel document
     * @throws IOException If any IO error occurs
     */
    public Workbook(final String path) throws IOException {
        this(new File(path));
    }

    /**
     * Devolve o nome da sheet.
     * 
     * @param index indice da sheet
     * @return o nome da sheet
     */
    public String getSheetName(final int index) {
        return this.workbook.getSheetName(index);
    }

    /**
     * Initializes this Workbook by reading the contents of the {@link HSSFWorkbook}.
     */
    private void initialize() {
        for (int i = 0; i < this.workbook.getNumberOfSheets(); i++) {
            HSSFSheet sheet = this.workbook.getSheetAt(i);
            Spreadsheet ss = new Spreadsheet(sheet);
            this.nameToSpreadsheet.put(this.workbook.getSheetName(i), ss);
            this.indexToSpreadsheet.put(i, ss);
        }
    }

    /**
     * Returns the number of Sheets on this Workbook.
     * 
     * @return int
     */
    public int getNumSheets() {
        return this.workbook.getNumberOfSheets();
    }

    /**
     * Returns a Spreadsheet given its index.
     * 
     * @param index int
     * @return {@link Spreadsheet}
     */
    public Spreadsheet getSpreadsheet(final int index) {
        return this.indexToSpreadsheet.get(index);
    }

    /**
     * Returns a Spreadsheet given its name.
     * 
     * @param name String
     * @return {@link Spreadsheet}
     */
    public Spreadsheet getSpreadsheet(final String name) {
        return this.nameToSpreadsheet.get(name);
    }

    /**
     * Return a name of the sheet on index
     * 
     * @param index int
     * @return {@link String}
     */
    public String getSpreadsheetName(final int index) {
        return this.workbook.getSheetName(index);
    }

    /**
     * Returns an Iterator for the Spreadsheets on this Workbook.
     * 
     * @return Iterator
     */
    public Iterator<Spreadsheet> iterator() {
        return this.indexToSpreadsheet.values().iterator();
    }
}
